#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
@file    : config.py
@brief   : 自适应光源算法模块配置文件
@author  : IPCS 2025电赛培训项目
@version : 1.0
@date    : 2025-07-15

@note    : 用户可通过修改此文件来调整算法参数，无需修改主代码
"""

# ========================= 硬件配置 =========================

# 摄像头配置
CAMERA_CONFIG = {
    'index': 0,                    # 摄像头索引 (0为默认摄像头)
    'width': 1920,                 # 图像宽度 (推荐: 640, 1280, 1920)
    'height': 1080,                # 图像高度 (推荐: 480, 720, 1080)
    'fps': 30,                     # 帧率 (推荐: 15, 30, 60)
    'format': 'MJPG'               # 图像格式 (MJPG, YUYV)
}

# 串口通信配置
UART_CONFIG = {
    'port': "/dev/ttyUSB0",        # 串口设备路径
    'baudrate': 115200,            # 波特率 (9600, 38400, 115200, 230400)
    'timeout': 1,                  # 超时时间 (秒)
    'frame_header': 0xAA55,        # 帧头标识
    'frame_end': 0x55AA,           # 帧尾标识
    'max_data_length': 256         # 最大数据长度
}

# ========================= 算法参数 =========================

# 自适应算法核心参数
ADAPTATION_CONFIG = {
    'target_brightness': 120,      # 目标亮度值 (0-255)
    'brightness_tolerance': 15,    # 亮度容忍度 (±值)
    'adaptation_speed': 0.3,       # 自适应速度 (0.1-1.0, 值越大响应越快)
    'min_exposure': 1,             # 最小曝光值
    'max_exposure': 10000,         # 最大曝光值
    'min_gain': 1.0,               # 最小增益
    'max_gain': 16.0,              # 最大增益
    'adaptation_interval': 0.1     # 自适应间隔 (秒)
}

# 光线检测阈值
LIGHT_DETECTION_CONFIG = {
    'overexposure_threshold': 250,        # 过曝阈值 (像素值)
    'underexposure_threshold': 15,        # 欠曝阈值 (像素值)
    'overexposure_ratio_limit': 0.05,     # 过曝比例限制 (5%)
    'underexposure_ratio_limit': 0.05,    # 欠曝比例限制 (5%)
    'contrast_threshold': 30,             # 对比度阈值
    'histogram_bins': 256                 # 直方图分组数
}

# 白平衡配置
WHITE_BALANCE_CONFIG = {
    'auto_wb_enabled': True,       # 自动白平衡开关
    'wb_adaptation_rate': 0.1,     # 白平衡适应速率
    'wb_temperature_range': (2800, 6500),  # 色温范围 (K)
    'wb_preset_indoor': 3200,      # 室内预设色温
    'wb_preset_outdoor': 5600,     # 室外预设色温
    'wb_preset_fluorescent': 4000  # 荧光灯预设色温
}

# ========================= 预设模式 =========================

# 预设场景参数
PRESET_MODES = {
    'indoor': {
        'name': '室内模式',
        'target_brightness': 100,
        'adaptation_speed': 0.2,
        'white_balance': 3200,
        'gain_bias': 1.2
    },
    'outdoor': {
        'name': '室外模式', 
        'target_brightness': 140,
        'adaptation_speed': 0.4,
        'white_balance': 5600,
        'gain_bias': 0.8
    },
    'low_light': {
        'name': '弱光模式',
        'target_brightness': 80,
        'adaptation_speed': 0.5,
        'white_balance': -1,  # 自动
        'gain_bias': 2.0
    },
    'high_contrast': {
        'name': '高对比度模式',
        'target_brightness': 120,
        'adaptation_speed': 0.3,
        'white_balance': -1,
        'gain_bias': 1.0,
        'contrast_enhancement': True
    },
    'sports': {
        'name': '运动模式',
        'target_brightness': 150,
        'adaptation_speed': 0.6,
        'white_balance': -1,
        'gain_bias': 0.7,
        'fast_shutter': True
    }
}

# ========================= 滤波参数 =========================

# 图像滤波配置
FILTER_CONFIG = {
    'enable_gaussian_blur': False,  # 高斯滤波开关
    'gaussian_kernel_size': 5,      # 高斯核大小
    'enable_bilateral_filter': False, # 双边滤波开关
    'bilateral_d': 9,               # 双边滤波邻域直径
    'bilateral_sigma_color': 75,    # 颜色空间滤波器sigma值
    'bilateral_sigma_space': 75,    # 坐标空间滤波器sigma值
    'enable_histogram_equalization': False,  # 直方图均衡化
    'enable_clahe': False,          # 限制对比度自适应直方图均衡
    'clahe_clip_limit': 2.0,        # CLAHE剪切限制
    'clahe_tile_size': (8, 8)       # CLAHE瓦片大小
}

# 时间滤波配置 (平滑参数变化)
TEMPORAL_FILTER_CONFIG = {
    'enable_smoothing': True,       # 参数平滑开关
    'smoothing_factor': 0.8,        # 平滑因子 (0-1, 值越大变化越平滑)
    'exposure_max_change': 0.2,     # 曝光最大变化率 (每次调节)
    'gain_max_change': 0.1,         # 增益最大变化率
    'brightness_max_change': 0.15   # 亮度最大变化率
}

# ========================= 性能配置 =========================

# 性能优化配置
PERFORMANCE_CONFIG = {
    'processing_threads': 3,        # 处理线程数
    'frame_skip_ratio': 0,          # 跳帧比例 (0-0.5)
    'roi_processing': False,        # 仅处理感兴趣区域
    'roi_rect': (0.25, 0.25, 0.5, 0.5),  # ROI区域 (x, y, w, h) 相对比例
    'downsample_ratio': 1,          # 降采样比例 (1, 2, 4)
    'enable_gpu_acceleration': False, # GPU加速 (需要OpenCV GPU支持)
    'memory_pool_size': 100         # 内存池大小 (帧数)
}

# 统计和监控配置
MONITORING_CONFIG = {
    'enable_fps_counter': True,     # FPS计数器
    'enable_performance_log': False, # 性能日志
    'log_interval': 5,              # 日志间隔 (秒)
    'enable_parameter_history': True, # 参数历史记录
    'history_length': 100,          # 历史记录长度
    'enable_auto_save': False,      # 自动保存配置
    'auto_save_interval': 300       # 自动保存间隔 (秒)
}

# ========================= 调试配置 =========================

# 调试模式配置
DEBUG_CONFIG = {
    'debug_mode': False,            # 调试模式总开关
    'show_histogram': False,        # 显示直方图
    'show_roi': False,              # 显示ROI区域
    'show_metrics_overlay': True,   # 显示指标覆盖层
    'log_level': 'INFO',            # 日志级别 (DEBUG, INFO, WARNING, ERROR)
    'save_debug_frames': False,     # 保存调试帧
    'debug_frame_interval': 30,     # 调试帧保存间隔
    'debug_output_dir': './debug_output' # 调试输出目录
}

# 可视化配置
VISUALIZATION_CONFIG = {
    'enable_preview': True,         # 预览窗口
    'preview_scale': 0.5,           # 预览缩放比例
    'overlay_color': (0, 255, 0),   # 覆盖层颜色 (BGR)
    'overlay_thickness': 2,         # 覆盖层线条粗细
    'font_scale': 0.7,              # 字体大小
    'show_exposure_indicator': True, # 显示曝光指示器
    'show_gain_indicator': True,    # 显示增益指示器
    'show_wb_indicator': True       # 显示白平衡指示器
}

# ========================= 通信协议 =========================

# STM32通信协议定义
COMMUNICATION_PROTOCOL = {
    'commands': {
        'STATUS_REPORT': 0x01,      # 状态报告
        'PARAM_UPDATE': 0x02,       # 参数更新
        'MODE_CHANGE': 0x03,        # 模式切换
        'CALIBRATION': 0x04,        # 校准命令
        'RESET': 0x05,              # 复位命令
        'HEARTBEAT': 0x06           # 心跳包
    },
    'response_codes': {
        'SUCCESS': 0x00,            # 成功
        'ERROR': 0x01,              # 错误
        'BUSY': 0x02,               # 忙碌
        'INVALID_CMD': 0x03,        # 无效命令
        'CHECKSUM_ERROR': 0x04      # 校验错误
    },
    'data_format': 'json',          # 数据格式 (json, binary)
    'enable_checksum': True,        # 启用校验
    'retry_count': 3,               # 重试次数
    'timeout': 1.0                  # 命令超时 (秒)
}

# ========================= 配置验证 =========================

def validate_config():
    """验证配置参数的合法性"""
    errors = []
    
    # 验证摄像头配置
    if CAMERA_CONFIG['width'] <= 0 or CAMERA_CONFIG['height'] <= 0:
        errors.append("摄像头分辨率必须大于0")
    
    if CAMERA_CONFIG['fps'] <= 0 or CAMERA_CONFIG['fps'] > 120:
        errors.append("摄像头帧率必须在1-120之间")
    
    # 验证自适应参数
    if not (0 <= ADAPTATION_CONFIG['target_brightness'] <= 255):
        errors.append("目标亮度必须在0-255之间")
    
    if not (0.1 <= ADAPTATION_CONFIG['adaptation_speed'] <= 1.0):
        errors.append("自适应速度必须在0.1-1.0之间")
    
    if ADAPTATION_CONFIG['min_exposure'] >= ADAPTATION_CONFIG['max_exposure']:
        errors.append("最小曝光值必须小于最大曝光值")
    
    if ADAPTATION_CONFIG['min_gain'] >= ADAPTATION_CONFIG['max_gain']:
        errors.append("最小增益必须小于最大增益")
    
    # 验证阈值参数
    light_config = LIGHT_DETECTION_CONFIG
    if light_config['underexposure_threshold'] >= light_config['overexposure_threshold']:
        errors.append("欠曝阈值必须小于过曝阈值")
    
    if not (0 <= light_config['overexposure_ratio_limit'] <= 1):
        errors.append("过曝比例限制必须在0-1之间")
    
    if not (0 <= light_config['underexposure_ratio_limit'] <= 1):
        errors.append("欠曝比例限制必须在0-1之间")
    
    return errors

def get_current_config():
    """获取当前配置摘要"""
    return {
        'camera': f"{CAMERA_CONFIG['width']}x{CAMERA_CONFIG['height']}@{CAMERA_CONFIG['fps']}fps",
        'target_brightness': ADAPTATION_CONFIG['target_brightness'],
        'adaptation_speed': ADAPTATION_CONFIG['adaptation_speed'],
        'uart_port': UART_CONFIG['port'],
        'debug_mode': DEBUG_CONFIG['debug_mode']
    }

def apply_preset_mode(mode_name):
    """应用预设模式"""
    if mode_name not in PRESET_MODES:
        raise ValueError(f"未知的预设模式: {mode_name}")
    
    preset = PRESET_MODES[mode_name]
    
    # 更新自适应配置
    ADAPTATION_CONFIG['target_brightness'] = preset.get('target_brightness', 120)
    ADAPTATION_CONFIG['adaptation_speed'] = preset.get('adaptation_speed', 0.3)
    
    # 更新白平衡配置
    WHITE_BALANCE_CONFIG['wb_preset'] = preset.get('white_balance', -1)
    
    print(f"已应用预设模式: {preset['name']}")

# ========================= 配置导出/导入 =========================

def save_config_to_file(filename="adaptive_light_config.json"):
    """保存配置到文件"""
    import json
    
    config_data = {
        'camera': CAMERA_CONFIG,
        'uart': UART_CONFIG,
        'adaptation': ADAPTATION_CONFIG,
        'light_detection': LIGHT_DETECTION_CONFIG,
        'white_balance': WHITE_BALANCE_CONFIG,
        'filter': FILTER_CONFIG,
        'performance': PERFORMANCE_CONFIG,
        'debug': DEBUG_CONFIG
    }
    
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(config_data, f, indent=4, ensure_ascii=False)
        print(f"配置已保存到: {filename}")
        return True
    except Exception as e:
        print(f"保存配置失败: {e}")
        return False

def load_config_from_file(filename="adaptive_light_config.json"):
    """从文件加载配置"""
    import json
    
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            config_data = json.load(f)
        
        # 更新全局配置
        globals().update({
            'CAMERA_CONFIG': config_data.get('camera', CAMERA_CONFIG),
            'UART_CONFIG': config_data.get('uart', UART_CONFIG),
            'ADAPTATION_CONFIG': config_data.get('adaptation', ADAPTATION_CONFIG),
            'LIGHT_DETECTION_CONFIG': config_data.get('light_detection', LIGHT_DETECTION_CONFIG),
            'WHITE_BALANCE_CONFIG': config_data.get('white_balance', WHITE_BALANCE_CONFIG),
            'FILTER_CONFIG': config_data.get('filter', FILTER_CONFIG),
            'PERFORMANCE_CONFIG': config_data.get('performance', PERFORMANCE_CONFIG),
            'DEBUG_CONFIG': config_data.get('debug', DEBUG_CONFIG)
        })
        
        print(f"配置已从文件加载: {filename}")
        return True
    except Exception as e:
        print(f"加载配置失败: {e}")
        return False

# ========================= 配置初始化检查 =========================

if __name__ == "__main__":
    print("自适应光源算法配置文件")
    print("=" * 40)
    
    # 验证配置
    errors = validate_config()
    if errors:
        print("配置验证失败:")
        for error in errors:
            print(f"  ✗ {error}")
    else:
        print("✓ 配置验证通过")
    
    # 显示当前配置摘要
    print("\n当前配置摘要:")
    config_summary = get_current_config()
    for key, value in config_summary.items():
        print(f"  {key}: {value}")
    
    # 显示可用预设模式
    print(f"\n可用预设模式:")
    for mode_name, mode_config in PRESET_MODES.items():
        print(f"  {mode_name}: {mode_config['name']}")
    
    # 提供配置保存选项
    try:
        save_option = input("\n是否保存当前配置到文件？(y/n): ").lower()
        if save_option == 'y':
            save_config_to_file()
    except KeyboardInterrupt:
        print("\n操作取消")
